package com.gaogzhen.datastructure.stack;

import java.util.EmptyStackException;
import java.util.Iterator;

/**
 * @author Administrator
 * @version 1.0
 * @description 栈
 * @date 2022-10-28 20:38
 */
public class Stack<E> implements Iterable<E> {

    /**
     * 栈顶指针
     */
    private Node<E> first;

    /**
     * 栈元素数量
     */
    private int size;

    /**
     * 判断栈是否为空
     * @return      是否为空
     */
    public boolean isEmpty() { return size == 0; }

    /**
     * 栈元素个数
     * @return  栈元素个数
     */
    public int size() { return  size; }

    /**
     * 压栈
     * @param e 元素e
     */
    public void push(E e) {
        Node<E> f = first;
        first = new Node<>(e, f);
        size++;
    }

    /**
     * 获取栈顶元素
     * @return  栈顶元素
     */
    public E peek() {
        if (size == 0) {
            throw new EmptyStackException();
        }
        return first.item;
    }


    /**
     * 弹栈
     * @return  栈顶元素
     */
    public E pop() {
        if (size == 0) {
            throw new EmptyStackException();
        }
        Node<E> f = first;
        first = first.next;
        E old = f.item;
        f.item = null;
        f.next = null;
        size--;
        return old;
    }

    /**
     * 迭代器
     * @return  迭代器
     */
    @Override
    public Iterator<E> iterator() {
        return new Itr();
    }

    @Override
    public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext()) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e);
            if (! it.hasNext()) {
                return sb.append(']').toString();
            }
            sb.append(',').append(' ');
        }
    }


    private class Node<E> {
        E item;
        Node<E> next;

        public Node(E item, Node<E> next) {
            this.item = item;
            this.next = next;
        }
    }

    private class Itr implements Iterator<E> {

        private Node<E> cur = first;

        @Override
        public boolean hasNext() {
            return cur != null;
        }

        @Override
        public E next() {
            E item = cur.item;
            cur = cur.next;
            return item;
        }

        /**
         * 栈只有顶弹出元素，所有此处不实现删除迭代删除
         */
        @Override
        public void remove() {}
    }
}
